﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

using com.vs.DataAccess;
using com.vs.DataAccess.DO;
using com.vs.General;
using com.vs.General.BL;

namespace com.vs.Shipping.BL
{
    public class PackingHelper
    {
        public string PackItemToNewContainer(Session sess, int iShpNum, string stContID, string stContType, List<PackingDS> ltPackDS)
        {
            ShippingContainerManager mgr = null;
            ShippingContainerDO scDO = null;
            string stErr = null;

            try
            {
                mgr = new ShippingContainerManager();
                if (StringManager.IsEmpty(stContID))
                {
                    stContID = NextNumberManager.GetNextNumber(sess, NextNumberConstants.stSHIP_CONT_ID);
                    if (StringManager.IsEmpty(stContID))
                        return MessageManager.MSG_SHP_014;//错误：无法生成发货货箱序号";
                }

                scDO = mgr.NewContainerHeader(sess, iShpNum, stContID, stContType, ref stErr);
                if (!StringManager.IsEmpty(stErr))
                    return stErr;

                return this.PackItemToContainer(sess, scDO.INTERNAL_CONTAINER_NUM, scDO.CONTAINER_ID, ltPackDS);
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
        }

        public string PackItemToContainer(Session sess, int iContNum, string stContID, List<PackingDS> ltPackDS)
        {
            string stErr = null;
            StringBuilder sbErr = null;
            ShipmentManager shMgr = null;
            int iShpNum = 0;
            ShippingContainerManager scMgr = null;

            scMgr = new ShippingContainerManager();
            if (!scMgr.DoesContainerExist(sess, iContNum))
                return MessageManager.MSG_SHP_008;//出库箱不存在";

            if (!scMgr.IsContainerOpen(sess, iContNum))
                return MessageManager.MSG_SHP_009; //出库箱已关闭

            sbErr = new StringBuilder();
            foreach (PackingDS packDS in ltPackDS)
            {
                iShpNum = packDS.INTERNAL_SHIPMENT_NUM;

                stErr = this.PackItem(sess,
                    packDS.INTERNAL_SHIPMENT_NUM,
                    packDS.INTERNAL_SHIPMENT_LINE_NUM,
                    packDS.QUANTITY,
                    packDS.ATTRIBUTE_NUM,
                    iContNum > 0 ? iContNum : packDS.INTERNAL_CONTAINER_NUM,
                    StringManager.IsEmpty(stContID) ? packDS.CONTAINER_ID : stContID);
                if (!StringManager.IsEmpty(stErr))
                {
                    sbErr.AppendLine(stErr);
                }
            }
            //更新出库单状态
            shMgr = new ShipmentManager();
            shMgr.UpdateShipmentStatus(sess, iShpNum);

            if (!StringManager.IsEmpty(sbErr))
                return sbErr.ToString();
            else
                return null;
        }

        private string PackItem(Session sess, 
            int iIntShpNum, 
            int iIntShpLnNum, 
            int iQty, 
            int iAttrNum, 
            int iContNum, 
            string stContID)
        {
            ShippingContainerManager mgr = null;
            ShippingContainerDO scDO = null;
            string stErr = null;
            int iContDtlNum = 0;

            try
            {
                mgr = new ShippingContainerManager();
                scDO = mgr.NewContainerDetail(sess, iIntShpLnNum, ref stErr);
                if (!StringManager.IsEmpty(stErr))
                    return stErr;

                scDO.PARENT = iContNum;
                scDO.PARENT_CONTAINER_ID = stContID;
                scDO.CONTAINER_TYPE = "-";
                scDO.QUANTITY = iQty;
                scDO.ATTRIBUTE_NUM = iAttrNum;
                stErr = scDO.Insert(sess);
                if (StringManager.IsErrorMessage(stErr))
                    return stErr;

                iContDtlNum = Convert.ToInt32(stErr);
                stErr = mgr.UpdateAttributes(sess, iContDtlNum);
                if (StringManager.IsErrorMessage(stErr))
                    return stErr;
                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
            finally
            {
            }
        }

        public string CloseContainer(Session sess, int iIntContNum)
        {
            ShippingContainerManager mgr = null;
            Dictionary<string, object> dcValue = null;
            ShippingContainerDO scDO = null;

            try
            {
                mgr = new ShippingContainerManager();
                if (!mgr.IsContainerOpen(sess, iIntContNum))
                    return MessageManager.MSG_SHP_009;//货箱已关闭

                scDO = new ShippingContainerDO();
                scDO.INTERNAL_CONTAINER_NUM = iIntContNum;
                dcValue = new Dictionary<string, object>();
                dcValue.Add("STATUS", (int)Constants.OutboundStatus.iSHIP_CONFIRM_PENDING);
                scDO.Update(sess, dcValue);
                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
        }

        public DataTable GetPackPendingDetails(Session sess, string stShipmentID, ref string stErr)
        {
            DataTable dtShp = null;

            try
            {
                dtShp = ShipmentHeaderDO.GetTableByColumn(sess, "SHIPMENT_ID", stShipmentID);
                if (DataManager.IsEmpty(dtShp))
                {
                    stErr = MessageManager.MSG_SHP_003; //不存在
                    return null;
                }
                else if (dtShp.Rows.Count > 1)
                {
                    stErr = MessageManager.MSG_SHP_012;//存在重复单号的出库单
                    return null;
                }

                return this.GetPackPendingDetails(sess, DataManager.GetInt(dtShp.Rows[0], "INTERNAL_SHIPMENT_NUM"), ref stErr);
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                stErr = MessageManager.MSG_GEN_000 + e.Message;
                return null;
            }
            finally
            {
            }
        }

        public DataTable GetPackPendingDetails(Session sess, int iIntShpNum, ref string stErr)
        {
            DataHelper helper = null;
            DataTable dtShp = null;
            string stSQL = "SHP_RPackPendingDetails";

            try
            {
                dtShp = ShipmentHeaderDO.GetTableByColumn(sess, "INTERNAL_SHIPMENT_NUM", iIntShpNum); 
                if (DataManager.IsEmpty(dtShp))
                {
                    stErr = MessageManager.MSG_SHP_003; //不存在
                    return null;
                }

                //如果未拣货或者已包装，返回错误提示
                int iLeadSts = DataManager.GetInt(dtShp.Rows[0], "LEADING_STS");
                int iTrailSts = DataManager.GetInt(dtShp.Rows[0], "TRAILING_STS");
                if (iLeadSts < (int)Constants.OutboundStatus.iPACKING_PENDING ||
                    iTrailSts > (int)Constants.OutboundStatus.iSHIP_CONFIRM_PENDING)
                {
                    stErr = MessageManager.MSG_SHP_011;//出库单不在可操作的状态范围内
                    return null;
                }

                helper = new DataHelper(sess);
                return helper.GetTable(CommandType.StoredProcedure, stSQL, new IDataParameter[]{
                        DataHelper.BuildParameter(sess, "@INTERNAL_SHIPMENT_NUM", iIntShpNum)});
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                stErr = MessageManager.MSG_GEN_000 + e.Message;
                return null;
            }
            finally
            {
                if (null != helper)
                    helper.Dispose();
            }
        }

        public string UnpackItem(Session sess, int iContDtlNum, int iQty)
        {
            DataHelper helper = null;

            try
            {
                //以下校验包含在SP中：
                //出库箱明细不存在
                //出库单不在可操作的状态范围内
                helper = new DataHelper(sess);
                return helper.GetString(CommandType.StoredProcedure, "SHP_UnpackItem", new IDataParameter[]{
                    DataHelper.BuildParameter(sess, "@INTERNAL_CONTAINER_NUM", iContDtlNum),
                    DataHelper.BuildParameter(sess, "@QUANTITY", iQty)});
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
            finally
            {
                if (helper != null)
                    helper.Dispose();
            }
        }

        public DataTable GetPackPendingDetails(Session sess, int iIntShpNum, string stItem, string stCompany, ref string stError)
        {
            DataHelper helper = null;

            try
            {
                helper = new DataHelper(sess);
                return helper.GetTable(CommandType.StoredProcedure, "SHP_RPackPendingDetail", new IDataParameter[]{
                        DataHelper.BuildParameter(sess, "@INTERNAL_SHIPMENT_NUM", iIntShpNum),
                        DataHelper.BuildParameter(sess, "@ITEM", stItem),
                        DataHelper.BuildParameter(sess, "@COMPANY", stCompany)
                    });
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                stError = MessageManager.MSG_GEN_000 + e.Message;
                return null;
            }
            finally
            {
                if (helper != null)
                    helper.Dispose();
            }
        }

        public string ValidateContainerID(Session sess, string stContID, int iIntShpNum, string stWarehouse)
        {
            DataHelper helper = null;

            try
            {
                helper = new DataHelper(sess);
                return helper.GetString(CommandType.StoredProcedure, "SHP_VContainerID", new IDataParameter[]{
                    DataHelper.BuildParameter(sess, "@CONTAINER_ID", stContID),
                    DataHelper.BuildParameter(sess, "@INTERNAL_SHIPMENT_NUM", iIntShpNum),
                    DataHelper.BuildParameter(sess, "@WAREHOUSE", stWarehouse)});
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
            finally
            {
                if (helper != null)
                    helper.Dispose();
            }
        }

        public int GetPackPendingQty(Session sess, int iIntShpLnNum, ref string stErr)
        {
            DataHelper helper = null;

            try
            {
                helper = new DataHelper(sess);
                return helper.GetInt(CommandType.StoredProcedure, "SHP_RPackPendingQty", new IDataParameter[]{
                    DataHelper.BuildParameter(sess, "@INTERNAL_SHIPMENT_LINE_NUM", iIntShpLnNum)});
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                stErr = MessageManager.MSG_GEN_000 + e.Message;
                return 0;
            }
            finally
            {
                if (null != helper)
                    helper.Dispose();
            }
        }
    }
}
